package com.aisino.inveli.vinda.controller;


import com.aisino.inveli.vinda.VindamanagerApplication;
import com.aisino.inveli.vinda.entity.*;
import com.aisino.inveli.vinda.service.CustomerService;
import com.aisino.inveli.vinda.service.InvEliService;
import com.aisino.inveli.vinda.task.InvEliTask;
import com.aisino.inveli.vinda.utils.AlertUtil;
import com.aisino.inveli.vinda.utils.ExcelUtils;
import com.aisino.inveli.vinda.utils.ProgressUtil;
import de.felixroske.jfxsupport.FXMLController;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.image.Image;
import javafx.scene.text.Text;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.Window;
import javafx.util.converter.DoubleStringConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;


/**
 * @author leifeng
 * @Date 2017-11-10
 **/
@FXMLController
public class InvEliController implements Initializable {

    private Logger logger = LoggerFactory.getLogger(InvEliController.class);

    //----------------------------购方信息--------------------------
    @FXML
    private Text billCode;
    @FXML
    private TextField invNum;
    @FXML
    private TextField phone;
    @FXML
    private TextField email;
    @FXML
    private TextField buyRegNum;
    @FXML
    private TextField buyName;
    @FXML
    private TextField buyBank;
    @FXML
    private TextField buyAddAndTel;

    //----------------------------销方信息---------------------------
    @FXML
    private TextField regNumber;
    @FXML
    private TextField salesName;
    @FXML
    private TextField salesBank;
    @FXML
    private TextField saleAddAndTel;

    //-------------------------------底部信息-------------------------------
    @FXML
    private TextField payee;
    @FXML
    private TextField checker;
    @FXML
    private TextField handler;
    @FXML
    private TextField content;

    //---------------------------------商品信息-------------------------------------
    @FXML
    private TableView<InvEliDetail> goodsTableView;
    @FXML
    private TableColumn<InvEliDetail,String> goodsName;
    @FXML
    private TableColumn<InvEliDetail,String> spec;
    @FXML
    private TableColumn<InvEliDetail,String> unit;
    @FXML
    private TableColumn<InvEliDetail,Double> price;
    @FXML
    private TableColumn<InvEliDetail,Double> num;
    @FXML
    private TableColumn<InvEliDetail,Double> amount;
    @FXML
    private TableColumn<InvEliDetail,String> rate;
    @FXML
    private TableColumn<InvEliDetail,Double> rateMon;

    @FXML
    private Text sumAmount;

    //-------------------------Service------------------------------
    @Resource
    private InvEliService invEliService;
    @Resource
    private CustomerService customerService;

    private InvEliInfo info;

    /**
     * 返回上一页
     * @param event 返回
     */
    @FXML
    public void gotoNext(ActionEvent event){
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/view/main.fxml"));
        // 获取原页面
        VindamanagerApplication.showView(fxmlLoader);
    }

    /**
     * 开票保存
     * @param event 开票
     */
    @FXML
    public void saveAction(ActionEvent event){
        Window window = ((Button) event.getSource()).getScene().getWindow();
        info.setGHF_EMAIL(email.getText());
        info.setGHF_SJ(phone.getText());
        info.setGHF_MC(buyName.getText());
        info.setGHF_NSRSBH(buyRegNum.getText());
        String[] strings = buyAddAndTel.getText().split(" ");
        if (strings.length == 1){
            info.setGHF_DZ(strings[0]);
        } else {
            info.setGHF_GDDH(strings[1]);
            info.setGHF_DZ(strings[0]);
        }
        info.setFHR(checker.getText());
        info.setSKR(payee.getText());
        info.setKPR(handler.getText());
        info.setBZ(content.getText());
        InvEliTask invEliTask = new InvEliTask(info,invEliService);
        invEliTask.valueProperty().addListener((observable, oldValue, returnElectronice) -> {
            if ("0000".equals(returnElectronice.getReturnCode().getValue())) {
                AlertUtil.showInfoAlert("","开票成功",window);
                invNum.setText(returnElectronice.getFPHM().getValue());
                logger.info(returnElectronice.getPDFURL().getValue());
            } else {
                AlertUtil.showErrAlert(returnElectronice.getReturnMsg().getValue(),window,"开具失败");
            }
        });
        ProgressUtil progressUtil = new ProgressUtil(invEliTask,window,"正在开票中,请稍后");
        progressUtil.activateProgressBar();
    }

    /**
     * 根据客户名称查询客户信息
     * @param event
     */
    @FXML
    public void searchCustomer(ActionEvent event){
        Stage stage = new Stage();
        Parent root;
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getClassLoader().getResource("view/customerSelect.fxml"));
        try {
            root = fxmlLoader.load();
            CustomerSelectController controller = fxmlLoader.getController();
            List<Customer> list = customerService.queryCusListByName(buyName.getText());
            controller.initData(list,customerService);
            stage.setScene(new Scene(root));
            stage.setTitle("客户信息");
            stage.initModality(Modality.APPLICATION_MODAL);
            stage.setResizable(false);
            stage.getIcons().add(new Image("/image/icon.png"));
            stage.initOwner(((Node) event.getSource()).getScene().getWindow());
            stage.show();
            stage.setOnHidden(t->{
                Customer customer = customerService.queryCusBySelected();
                buyName.setText(customer.getCusName());
                buyRegNum.setText(customer.getRegNumber());
                buyAddAndTel.setText(customer.getAddAndTel());
                buyBank.setText(customer.getBank());
                email.setText(customer.getEmail());
            });
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 上一页转送过来
     * @param sysGoodList 商品信息
     * @param sysConfigEntity 发票基础信息
     */
    public void initData(GoodsList sysGoodList, ConfigEntity sysConfigEntity) {
        regNumber.setText(sysConfigEntity.getRegNumber());
        salesName.setText(sysConfigEntity.getSalesName());
        salesBank.setText(sysConfigEntity.getSalesBank());
        saleAddAndTel.setText(sysConfigEntity.getSalesAddress()+" "+sysConfigEntity.getSalesTel());
        payee.setText(sysConfigEntity.getPayee());
        checker.setText(sysConfigEntity.getChecker());
        handler.setText(sysConfigEntity.getHandler());
        //根据txt表头客户资料匹配客户信息
        String[] header = ExcelUtils.getHeaderArray(sysGoodList.getHeaderStr());
        Customer customer = customerService.queryCusByName(header);
        billCode.setText(header[0]);
        buyName.setText(customer.getCusName());
        buyRegNum.setText(customer.getRegNumber());
        buyAddAndTel.setText(customer.getAddAndTel());
        buyBank.setText(customer.getBank());
        email.setText(customer.getEmail()==null?"":customer.getEmail());
        //转换
        info = invEliService.packageBean(sysGoodList,sysConfigEntity);
        showGoodsTableView(info.getDetailList());
    }

    /**
     * 初始化tableview
     * @param goodsList 商品列表
     */
    private void showGoodsTableView(List<InvEliDetail> goodsList) {
        goodsName.setCellValueFactory(new PropertyValueFactory<>("XMMC"));
        spec.setCellValueFactory(new PropertyValueFactory<>("GGXH"));
        unit.setCellValueFactory(new PropertyValueFactory<>("DW"));
        num.setCellValueFactory(new PropertyValueFactory<>("XMSL"));
        price.setCellValueFactory(new PropertyValueFactory<>("XMDJ"));
        amount.setCellValueFactory(new PropertyValueFactory<>("XMJE"));
        rate.setCellValueFactory(new PropertyValueFactory<>("SL"));
        rateMon.setCellValueFactory(new PropertyValueFactory<>("SE"));
        ObservableList<InvEliDetail> list = FXCollections.observableArrayList();
        BigDecimal totalAmount = new BigDecimal(0);
        BigDecimal totalRateAmount = new BigDecimal(0);
        for (InvEliDetail inv: goodsList) {
            totalAmount = totalAmount.add(new BigDecimal(inv.getXMJE()));
            totalRateAmount = totalRateAmount.add(new BigDecimal(inv.getSE()));
            list.add(inv);
        }
        InvEliDetail invEliDetail = new InvEliDetail();
        invEliDetail.setXMMC("合计");
        invEliDetail.setXMJE(totalAmount.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
        invEliDetail.setSE(totalRateAmount.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
        sumAmount.setText(totalAmount.setScale(2,BigDecimal.ROUND_HALF_UP).toString());
        list.add(invEliDetail);
        goodsTableView.setItems(list);
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        goodsTableView.setEditable(true);
        //商品名称可修改
        goodsName.setCellFactory(TextFieldTableCell.forTableColumn());
        goodsName.setOnEditCommit(event -> {
            int index = goodsTableView.getSelectionModel().getSelectedIndex();
            InvEliDetail eliDetail = goodsTableView.getSelectionModel().getSelectedItem();
            String newName = event.getNewValue();
            eliDetail.setXMMC(newName);
            info.getDetailList().get(index).setXMMC(newName);
        });
        //规格型号可修改
        spec.setCellFactory(TextFieldTableCell.forTableColumn());
        spec.setOnEditCommit(event -> {
            int index = goodsTableView.getSelectionModel().getSelectedIndex();
            InvEliDetail eliDetail = goodsTableView.getSelectionModel().getSelectedItem();
            String newName = event.getNewValue();
            eliDetail.setGGXH(newName);
            info.getDetailList().get(index).setGGXH(newName);
        });
        //单位可修改
        unit.setCellFactory(TextFieldTableCell.forTableColumn());
        unit.setOnEditCommit(event -> {
            int index = goodsTableView.getSelectionModel().getSelectedIndex();
            InvEliDetail eliDetail = goodsTableView.getSelectionModel().getSelectedItem();
            String newName = event.getNewValue();
            eliDetail.setDW(newName);
            info.getDetailList().get(index).setDW(newName);
        });
        //--------------------以下列修改需重新计算单价，金额，税额等关系-----------------
        //数量可修改
        num.setCellFactory(TextFieldTableCell.forTableColumn(new DoubleStringConverter()));
        num.setOnEditCommit(event -> {
            int index = goodsTableView.getSelectionModel().getSelectedIndex();
            InvEliDetail eliDetail = goodsTableView.getSelectionModel().getSelectedItem();
            //新单价
            Double newValue = event.getNewValue();
            //重新计算单价
            BigDecimal price = new BigDecimal(eliDetail.getXMJE()).divide(new BigDecimal(newValue),8,BigDecimal.ROUND_HALF_UP);
            eliDetail.setXMSL(newValue);
            eliDetail.setXMDJ(price.doubleValue());
            info.getDetailList().get(index).setXMSL(newValue);
            info.getDetailList().get(index).setXMDJ(price.doubleValue());
            goodsTableView.refresh();
        });
        //修改金额
        amount.setCellFactory(TextFieldTableCell.forTableColumn(new DoubleStringConverter()));
        amount.setOnEditCommit(event -> {
            int index = goodsTableView.getSelectionModel().getSelectedIndex();
            InvEliDetail eliDetail = goodsTableView.getSelectionModel().getSelectedItem();
            ObservableList<InvEliDetail> items = goodsTableView.getItems();
            Double oldValue = event.getOldValue();
            //新金额
            Double newValue = event.getNewValue();
            //重新计算单价
            BigDecimal price = new BigDecimal(newValue).divide(new BigDecimal(eliDetail.getXMSL()),8,BigDecimal.ROUND_HALF_UP);
            //重新计算税额
            BigDecimal se = new BigDecimal(newValue).divide(
                    new BigDecimal(1).add(new BigDecimal(eliDetail.getSL())),8,BigDecimal.ROUND_HALF_UP)
                    .multiply(new BigDecimal(eliDetail.getSL())).setScale(2,BigDecimal.ROUND_HALF_UP);
            eliDetail.setXMJE(newValue);
            Double oldSe = eliDetail.getSE();
            eliDetail.setSE(se.doubleValue());
            eliDetail.setXMDJ(price.doubleValue());
            //重新计算合计金额
            BigDecimal newAmount = new BigDecimal(items.get(items.size()-1).getXMJE())
                    .subtract(new BigDecimal(oldValue)).add(new BigDecimal(newValue)).setScale(2,BigDecimal.ROUND_HALF_UP);
            items.get(items.size()-1).setXMJE(newAmount.doubleValue());
            //设置新金额
            info.getDetailList().get(index).setXMJE(newValue);
            //重新计算合计税额
            BigDecimal newRateAmount = new BigDecimal(items.get(items.size() - 1).getSE())
                    .subtract(new BigDecimal(oldSe)).add(se).setScale(2,BigDecimal.ROUND_HALF_UP);
            //重新计算合计税额
            items.get(items.size()-1).setSE(newRateAmount.doubleValue());
            info.getDetailList().get(index).setXMJE(newValue);
            info.getDetailList().get(index).setSE(se.doubleValue());
            info.getDetailList().get(index).setXMDJ(price.doubleValue());
            //价税合计重新计算
            sumAmount.setText(newAmount.toString());
            goodsTableView.refresh();
        });
        //修改单价
        price.setCellFactory(TextFieldTableCell.forTableColumn(new DoubleStringConverter()));
        price.setOnEditCommit(event -> {
            int index = goodsTableView.getSelectionModel().getSelectedIndex();
            InvEliDetail eliDetail = goodsTableView.getSelectionModel().getSelectedItem();
            ObservableList<InvEliDetail> items = goodsTableView.getItems();
            Double newValue = event.getNewValue();
            eliDetail.setXMDJ(newValue);
            //重新计算项目金额
            BigDecimal amount = new BigDecimal(newValue).multiply(new BigDecimal(eliDetail.getXMSL()))
                    .setScale(2,BigDecimal.ROUND_HALF_UP);
            //获取原金额
            Double xmje = eliDetail.getXMJE();
            eliDetail.setXMJE(amount.doubleValue());
            info.getDetailList().get(index).setXMJE(amount.doubleValue());
            //重新计算税额
            Double oldSe = eliDetail.getSE();
            BigDecimal se = amount.divide(
                    new BigDecimal(1).add(new BigDecimal(eliDetail.getSL())),8,BigDecimal.ROUND_HALF_UP)
                    .multiply(new BigDecimal(eliDetail.getSL())).setScale(2,BigDecimal.ROUND_HALF_UP);
            eliDetail.setSE(se.doubleValue());
            //重新计算总金额，总税额
            BigDecimal amountTotal = new BigDecimal(items.get(items.size() - 1).getXMJE())
                    .subtract(new BigDecimal(xmje)).add(new BigDecimal(newValue)).setScale(2,BigDecimal.ROUND_HALF_UP);
            BigDecimal rateTotal = new BigDecimal(items.get(items.size() - 1).getSE())
                    .subtract(new BigDecimal(oldSe)).add(se).setScale(2,BigDecimal.ROUND_HALF_UP);
            items.get(items.size()-1).setXMJE(amountTotal.doubleValue());
            items.get(items.size()-1).setSE(rateTotal.doubleValue());
            sumAmount.setText(amountTotal.toString());
            goodsTableView.refresh();
        });
    }
}
